//
//  DataEncrptDES.m
//  U_Airplane
//
//  Created by iOS on 2017/11/1.
//  Copyright © 2017年 iOS. All rights reserved.
//

#import "DataEncrptDES.h"
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>

@implementation DataEncrptDES

+(NSString *) decryptUseDES:(NSString*)cipherText key:(NSString*)key {
    // 利用 GTMBase64 解碼 Base64 字串
    
    NSData* cipherData = [[NSData alloc] initWithBase64EncodedString:cipherText options:0];//base64DecodedData
    unsigned char buffer[1024];  //注意空间大小
    memset(buffer, 0, sizeof(char));
    size_t numBytesDecrypted = 0;
    
    // IV 偏移量不需使用
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          [key UTF8String],
                                          kCCKeySizeDES,
                                          nil,
                                          [cipherData bytes],
                                          [cipherData length],
                                          buffer,
                                          1024,  //注意空间大小
                                          &numBytesDecrypted);
    NSString* plainText = nil;
    if (cryptStatus == kCCSuccess) {
        NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
        plainText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }
    return plainText;
}


+(NSString *) encryptUseDES:(NSString *)clearText key:(NSString *)key
{
    NSData *data = [clearText dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    unsigned char buffer[1024];  //注意空间大小
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          [key UTF8String],
                                          kCCKeySizeDES,
                                          nil,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          1024,  //注意空间大小
                                          &numBytesEncrypted);
    
    NSString* plainText = nil;
    if (cryptStatus == kCCSuccess) {
        NSData *dataTemp = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        plainText = [dataTemp base64EncodedStringWithOptions:0];//base64EncodedString
    }else{
        //        NSLog(@"DES加密失败");
    }
    return plainText;
}

//签名算法
//签名生成的通用步骤如下：
//第一步，设所有发送或者接收到的数据为集合M，将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。
//特别注意以下重要规则：
//◆ 参数名ASCII码从小到大排序（字典序）；
//◆ 如果参数的值为空不参与签名；
//◆ 参数名区分大小写；


+(NSString *)signStr:(NSMutableDictionary*)dict
{
    NSMutableString *contentString  = [NSMutableString string];
    [contentString appendFormat:@"{"];
    
    NSArray *keys = [dict allKeys];
    //按字母顺序排序
    NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    
    NSMutableString *paramStr = [NSMutableString string];
    [paramStr appendFormat:@"{"];
    
    //拼接字符串
    for (int i = 0; i < sortedArray.count; i++) {
        NSString *categoryId = sortedArray[i];
        if ([[dict objectForKey:categoryId] isKindOfClass:[NSDictionary class]]) {
            NSDictionary *subDict = dict[categoryId];
            NSArray *keys = [subDict allKeys];
            for (int j = 0; j < keys.count; j++) {
                NSString *key = keys[j];
                if (![subDict[key] isEqualToString:@""] && ![subDict[key] isEqualToString:@"sign"] && ![subDict[key] isEqualToString:@"key"])
                {
                    [paramStr appendFormat:@"\"%@\":\"%@\"", key, [subDict objectForKey:key]];
                    if (j < keys.count-1) {
                        [paramStr appendFormat:@","];
                    }
                }
            }
            [paramStr appendFormat:@"}"];
            
            [contentString appendFormat:@"\"%@\":\"%@\",", categoryId, paramStr];
        }else if ([categoryId isEqualToString:@"file"]){
            
        } else{
            if (![dict[categoryId] isEqualToString:@""] && ![dict[categoryId] isEqualToString:@"sign"] && ![dict[categoryId] isEqualToString:@"key"])
            {
                [contentString appendFormat:@"\"%@\":\"%@\"", categoryId, [dict objectForKey:categoryId]];
                if (i < sortedArray.count-1) {
                    [contentString appendFormat:@","];
                }
            }
        }
    }
    [contentString appendFormat:@"}"];
    //HMACMD5
    NSString *signStr = [self encryptUseDES:contentString key:Data_Secret_Key];
    return signStr;
}

//+ (NSString *)HMACMD5WithString:(NSString *)toEncryptStr WithKey:(NSString *)keyStr
//{
//    const char *cKey  = [keyStr cStringUsingEncoding:NSUTF8StringEncoding];
//    const char *cData = [toEncryptStr cStringUsingEncoding:NSUTF8StringEncoding];
//    const unsigned int blockSize = 64;
//    char ipad[blockSize];
//    char opad[blockSize];
//    char keypad[blockSize];
//
//    unsigned int keyLen = strlen(cKey);
//    CC_MD5_CTX ctxt;
//    if (keyLen > blockSize) {
//        CC_MD5_Init(&ctxt);
//        CC_MD5_Update(&ctxt, cKey, keyLen);
//        CC_MD5_Final((unsigned char *)keypad, &ctxt);
//        keyLen = CC_MD5_DIGEST_LENGTH;
//    }
//    else {
//        memcpy(keypad, cKey, keyLen);
//    }
//
//    memset(ipad, 0x36, blockSize);
//    memset(opad, 0x5c, blockSize);
//
//    int i;
//    for (i = 0; i < keyLen; i++) {
//        ipad[i] ^= keypad[i];
//        opad[i] ^= keypad[i];
//    }
//
//    CC_MD5_Init(&ctxt);
//    CC_MD5_Update(&ctxt, ipad, blockSize);
//    CC_MD5_Update(&ctxt, cData, strlen(cData));
//    unsigned char md5[CC_MD5_DIGEST_LENGTH];
//    CC_MD5_Final(md5, &ctxt);
//
//    CC_MD5_Init(&ctxt);
//    CC_MD5_Update(&ctxt, opad, blockSize);
//    CC_MD5_Update(&ctxt, md5, CC_MD5_DIGEST_LENGTH);
//    CC_MD5_Final(md5, &ctxt);
//
//    const unsigned int hex_len = CC_MD5_DIGEST_LENGTH*2+2;
//    char hex[hex_len];
//    for(i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
//        snprintf(&hex[i*2], hex_len-i*2, "%02x", md5[i]);
//    }
//
//    NSData *HMAC = [[NSData alloc] initWithBytes:hex length:strlen(hex)];
//    NSString *hashStr = [[NSString alloc] initWithData:HMAC encoding:NSUTF8StringEncoding] ;
//    NSString *hash= [hashStr uppercaseString];
//
//    return hash;
//}

@end
